package cn.xiaopengstack.infrastructure.persistent.repository;

import cn.bugstack.middleware.db.router.strategy.IDBRouterStrategy;
import cn.xiaopengstack.domain.award.event.SendAwardMessageEvent;
import cn.xiaopengstack.domain.award.model.valobj.TaskStateVO;
import cn.xiaopengstack.domain.strategy.model.entity.UserEntity;
import cn.xiaopengstack.domain.task.model.TaskEntity;
import cn.xiaopengstack.domain.task.repository.ITaskRepository;
import cn.xiaopengstack.infrastructure.event.EventPublisher;
import cn.xiaopengstack.infrastructure.persistent.dao.ITaskDao;
import cn.xiaopengstack.infrastructure.persistent.po.Task;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author jiangyangang
 */
@Repository
@Slf4j
public class TaskRepository implements ITaskRepository {

    @Resource
    private ITaskDao taskDao;

    @Resource
    private IDBRouterStrategy dbRouter;

    @Resource
    private EventPublisher eventPublisher;

    @Override
    public List<TaskEntity> queryFailedTask(Integer db) {
        List<TaskEntity> taskEntities = Collections.emptyList();
        try {
            dbRouter.setDBKey(db);
            dbRouter.setTBKey(0);
            List<Task> tasks = taskDao.queryNoSendMessageTaskList();
            taskEntities = tasks.stream().map(task -> {
                TaskEntity taskEntity = new TaskEntity();
                BeanUtils.copyProperties(task, taskEntity);
                taskEntity.setState(TaskStateVO.valueOf(task.getState()));
                taskEntity.setUser(UserEntity.builder().userId(task.getUserId()).build());
                return taskEntity;
            }).collect(Collectors.toList());
        } finally {
            dbRouter.clear();
        }
        return taskEntities;
    }

    @Override
    public void sendTaskMq(TaskEntity taskEntity) {
        eventPublisher.publish(taskEntity.getMessage(), taskEntity.getTopic());
    }

    @Override
    public void updateTaskSendMessageFail(TaskEntity taskEntity) {
        try {
            log.info("updateTaskSendMessageFail {}", taskEntity.getUser().getUserId());
            dbRouter.doRouter(taskEntity.getUser().getUserId());
            Task task = new Task();
            task.setMessageId(taskEntity.getMessageId());
            task.setUserId(task.getUserId());
            taskDao.updateTaskSendMessageFail(task);
        } finally {
            dbRouter.clear();
        }
    }

    @Override
    public void updateTaskSendMessageCompleted(TaskEntity taskEntity) {
        try {
            log.info("updateTaskSendMessageCompleted {}", taskEntity.getUser().getUserId());
            dbRouter.doRouter(taskEntity.getUser().getUserId());
            Task task = new Task();
            task.setMessageId(taskEntity.getMessageId());
            task.setUserId(taskEntity.getUser().getUserId());
            taskDao.updateTaskSendMessageCompleted(task);
        } finally {
            dbRouter.clear();
        }
    }
}
